#include "dynamicgesture.h"
#include "eventmanager.h"
#include "dynamicevent.h"

#include <string>

using namespace mlgesture;
using namespace std;

DynamicGesture::DynamicGesture(const vector<QString> &model_files, const QString &garbage_file, int hands_num) throw (HandGestureException) {
	for (vector<QString>::const_iterator it = model_files.begin(); it != model_files.end(); ++it) {
		Hmm* model_tmp = new Hmm();
		model_tmp->read(*it);
		gesturesModels_.push_back(model_tmp);
	}
	garbageModel_.read(garbage_file);
	dynamicGestures_.resize(hands_num, -1);
}

DynamicGesture::~DynamicGesture() {
	for (vector<Hmm*>::iterator it = gesturesModels_.begin(); it != gesturesModels_.end(); ++it) {
		delete *it;
	}
}

const vector<int>& DynamicGesture::getDynamicGestures() throw (HandGestureException) {
	return dynamicGestures_;
}
#include <iostream>
void DynamicGesture::process(const vector<Trajectory> &trajectory, const vector<bool> &trajectory_end) throw (HandGestureException) {
	if (gesturesModels_.size() == 0 || garbageModel_.getStatesNum() <= 0)
		throw HandGestureException("Dynamic gestures data model is empty");
	for (size_t i=0; i<dynamicGestures_.size(); i++) {
		if (trajectory_end[i] && trajectory[i].data_.size() >= 5) {
			const vector<int> &data = trajectory[i].data_;
			double max_prob = 0;
			int max_model = -1;
			for (size_t j=0; j<gesturesModels_.size(); j++) {
				double prob = gesturesModels_[j]->viterbi(data);
				if (prob > max_prob) {
					max_prob = prob;
					max_model = j;	
				}
				//cout << j << " " << prob << "; ";
			}
			//cout << endl;

			double garbage_prob = garbageModel_.viterbi(data);
			if (garbage_prob > max_prob) {
				dynamicGestures_[i] = -1;
			}
			else {
				dynamicGestures_[i] = max_model;
				DynamicEvent *event = new DynamicEvent(i, max_model);
				EventManager::getInstance().sendEvent(event);
				delete event;
			}
		}
		else {
			dynamicGestures_[i] = -1;
		}
	}
}
